//
//  RZConversationDataSource.m
//  RZIM
//
//  Created by reyzhang on 2021/8/19.
//

#import "RZConversationDataSource.h"
#import "RZMessage.h"
#import "RZConversation.h"
#import "RZConversationViewController.h"
#import "RZIMClient.h"
#import "RZMessageInfo.h"



#define COLLECTION_VIEW_REFRESH_CONTROL_HEIGHT 30
#define COLLECTION_VIEW_CELL_MAX_COUNT 3000
#define COLLECTION_VIEW_CELL_REMOVE_COUNT 200

@interface RZConversationDataSource ()


@property (nonatomic, weak) RZConversationViewController *chatVC;
@property (nonatomic, strong) NSOperationQueue *appendMessageQueue;

@property (nonatomic, assign) BOOL loadHistoryMessageFromRemote;
@property (nonatomic, assign) BOOL isLoadingHistoryMessage;//是否正在加载历史消息
@property (nonatomic, assign) BOOL allMessagesAreLoaded; /// YES  表示所有消息都已加载完 NO 表示还有剩余消息
@property (nonatomic, assign) BOOL isIndicatorLoading;

@property (nonatomic, assign) long long recordTime;
@property (nonatomic, assign) long long showUnreadViewMessageId; //显示查看未读的消息 id

//第一条未读消息,进入会话时存储起来，因为加载消息之后会改变所有消息的未读状态
@property (nonatomic, strong) RZMessage *firstUnreadMessage;
@property (nonatomic, strong) RZConversation *conversation;
@property (nonatomic, assign) NSInteger page;
@end


@implementation RZConversationDataSource

- (instancetype)init:(RZConversationViewController *)chatVC {
    self = [super init];
    if(self) {
        self.chatVC = chatVC;
        self.loadHistoryMessageFromRemote = NO;
        self.allMessagesAreLoaded = YES;
        self.isIndicatorLoading = NO;
        self.unreadNewMsgArr = [NSMutableArray new];

        self.page = 1;
        
        self.appendMessageQueue = [NSOperationQueue new];
        self.appendMessageQueue.maxConcurrentOperationCount = 1;
        self.appendMessageQueue.name = @"im.reyzhang.appendMessageQueue";
    }
    return self;
}



#pragma mark - 消息数据源处理
- (void)getInitialMessage:(RZConversation *)conversation {
    self.conversation = conversation;
    if(self.chatVC.conversationType == ConversationType_CHATROOM) {
        //聊天室从服务器拉取消息，设置初始状态为为加载完成
//        [self joinChatRoomIfNeed];
    }else {
        //非聊天室加载历史数据
        [self loadLatestHistoryMessage];
        self.chatVC.unReadMessage = conversation.groupInfo.notReadCnt;
        if (self.chatVC.unReadMessage) {
//            self.firstUnreadMessage =
//                [[RCIMClient sharedRCIMClient] getFirstUnreadMessage:self.chatVC.conversationType targetId:self.chatVC.targetId];
        }
    }
}

//- (void)appendAndDisplayMessage:(RZMessage *)rzMessage {
//    if (!rzMessage) {
//        return;
//    }
////    __weak typeof(self) ws = self;
//    RZConversationViewController *chatVC = self.chatVC;
//    [self.appendMessageQueue addOperationWithBlock:^{
//        dispatch_async(dispatch_get_main_queue(), ^{
//            @autoreleasepool {
//                if (!chatVC.needAutoScrollToBottom) {
//                    chatVC.needAutoScrollToBottom =
//                        [chatVC.conversationMessageCollectionView
//                            cellForItemAtIndexPath:[NSIndexPath indexPathForItem:chatVC.conversationDataRepository.count - 1
//                                                                       inSection:0]] != nil;
//                }
//
//
//            }
//        });
//        [NSThread sleepForTimeInterval:0.01];
//    }];
//}


/**
 加载最新的历史消息
 */
- (void)loadLatestHistoryMessage {
    self.loadHistoryMessageFromRemote = YES;
    
    [[RZIMClient sharedClient] getHistoryMessageWithTargetId:self.chatVC.targetId
                                                        page:self.page pageSize:self.chatVC.defaultRemoteHistoryMessageCount
                                                     success:^(NSArray<RZMessageInfo *> * _Nonnull dataSource,NSInteger totalPage) {
        [self.chatVC.collectionViewHeader stopAnimating];
        self.allMessagesAreLoaded = (self.page == totalPage); //当前页与总页数相等 表示已经全部加载完毕
        if (self.page == 1) {
            self.chatVC.conversationDataRepository = dataSource.mutableCopy;
            [self.chatVC.conversationMessageCollectionView reloadData];
            [self.chatVC scrollToBottomAnimated:NO];
        }else {
            [self handleMessagesAfterLoadMore:dataSource];
        }
        
        
    } error:^(RZErrorCode nErrorCode, NSString * _Nullable errorMessage) {
        
    }];
}





- (void)scrollToLoadMoreHistoryMessage {
    self.isIndicatorLoading = YES;
    [self performSelector:@selector(loadMoreHistoryMessage) withObject:nil afterDelay:0.5f];
}


/**
 下拉，加载更多历史消息
 */
- (void)loadMoreHistoryMessageIfNeed {
    if (!self.isIndicatorLoading && !self.allMessagesAreLoaded) {
        self.isIndicatorLoading = YES;
        [self loadMoreHistoryMessage];
    }
}

- (void)loadMoreHistoryMessage {

    self.page ++;
    [self loadLatestHistoryMessage];
}



- (void)handleMessagesAfterLoadMore:(NSArray *)__messageArray {
    if (![__messageArray isKindOfClass:[NSArray class]]) {
        return;
    }
    
    CGFloat increasedHeight = 0;
    NSMutableArray *indexPathes = [[NSMutableArray alloc] initWithCapacity:self.chatVC.defaultRemoteHistoryMessageCount];

    int indexPathCount = 0;
    
    //倒序拿到的接口数据
    for (NSInteger i = __messageArray.count-1; i >= 0 ; i--) {
        RZMessageInfo *model = [__messageArray objectAtIndex:i];
        if (!model || ![model isKindOfClass:[RZMessageInfo class]]) {
            continue;
        }
        
        if (self.chatVC.conversationDataRepository.count > 0) {
            
            //向顶部插入数据
            [self.chatVC.conversationDataRepository insertObject:model atIndex:0];
            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:indexPathCount++ inSection:0];
            if (indexPath) {
                [indexPathes addObject:indexPath];
            }
            //获取每个项的高度
            CGSize itemSize = [self.chatVC collectionView:self.chatVC.conversationMessageCollectionView
                                            layout:self.chatVC.flowLayout
                            sizeForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
            increasedHeight += itemSize.height; //累加所有高度
        }
    }

    if (self.chatVC.conversationDataRepository.count <= 0) {
        return;
    }

    if (indexPathes.count <= 0) {
        return;
    }

    CGSize contentSize = self.chatVC.conversationMessageCollectionView.contentSize;
    contentSize.height += increasedHeight; //变更contentSize的高度， 将累加高度计算进去
    if (self.allMessagesAreLoaded) { //判断所有的数据是否已经全部加载完毕
        contentSize.height -= COLLECTION_VIEW_REFRESH_CONTROL_HEIGHT; //全部加载完毕，去掉下拉刷新控件所占的高度
    }
    self.chatVC.flowLayout.collectionViewNewContentSize = contentSize; //重置contentSize
    
    if (indexPathes.count <= 0) {
        return;
    }
    
    [UIView setAnimationsEnabled:NO]; //忽略掉任何的属性改变
    
    @try {
        if (self.chatVC.conversationDataRepository.count == 1 ||
            [self.chatVC.conversationMessageCollectionView numberOfItemsInSection:0] ==
                self.chatVC.conversationDataRepository.count) {
            [self.chatVC.conversationMessageCollectionView reloadData];
        } else {
            [self.chatVC.conversationMessageCollectionView insertItemsAtIndexPaths:indexPathes];
        }
        
        
        [UIView setAnimationsEnabled:YES];
        
        //停止菊花加载动画
        [self.chatVC.collectionViewHeader stopAnimating];
        self.isIndicatorLoading = NO;
        
        //
        if (self.allMessagesAreLoaded) {
            UICollectionViewLayout *layout = self.chatVC.conversationMessageCollectionView.collectionViewLayout;
            //设置当前布局无效,同时触发布局更新，可以在任何时间调用该方法更新布局信息。
            [self.chatVC.conversationMessageCollectionView.collectionViewLayout invalidateLayout];
            [self.chatVC.conversationMessageCollectionView setCollectionViewLayout:layout];
        }
    } @catch (NSException *except) {
        NSLog(@"----handleMessagesAfterLoadMore %@", except.description);
    }
}


#pragma mark - Notification Selector
- (void)didReceiveMessageNotification:(RZMessage *)message {
    __block RZMessage *rzMessage = message;
    
    //将socket消息转成 消息模型
    RZMessageInfo *model = [RZMessageInfo createWithSocketMessage:rzMessage];
    
    //先判断是否为当前会话
    if ([model.gid isEqualToString:self.chatVC.targetId]) {
        if (self.chatVC.isConversationAppear) {
            
        } else {
            self.chatVC.unReadMessage++;
        }
        
        
        __weak typeof(self) weakSelf = self;
        dispatch_async(dispatch_get_main_queue(), ^{
            //数量不可能无限制的大，这里限制收到消息过多时，就对显示消息数量进行限制。
            //用户可以手动下拉更多消息，查看更多历史消息。
            [weakSelf clearOldestMessagesWhenMemoryWarning];
            rzMessage = [self.chatVC willAppendAndDisplayMessage:rzMessage];
            if (rzMessage) {
                if (!self.isLoadingHistoryMessage) {
                    [weakSelf appendAndDisplayMessage:rzMessage];
                }
//                if (model.messageDirection == MessageDirection_SEND) {
//                    [self.appendMessageQueue addOperationWithBlock:^{
//                        dispatch_async(dispatch_get_main_queue(), ^{
//                            [weakSelf.chatVC updateForMessageSendSuccess:rcMessage.messageId content:rcMessage.content];
//                        });
//                    }];
//                }
            }
        });
    }
}

//数量不可能无限制的大，这里限制收到消息过多时，就对显示消息数量进行限制。
//用户可以手动下拉更多消息，查看更多历史消息。
- (void)clearOldestMessagesWhenMemoryWarning {
    if (self.chatVC.conversationDataRepository.count > COLLECTION_VIEW_CELL_MAX_COUNT) {
        NSArray *array = [self.chatVC.conversationMessageCollectionView indexPathsForVisibleItems];
        if (array.count > 0) {
            NSIndexPath *indexPath = array.firstObject;
            //当前可见的 cell 是否在即将清理的 200
            //条数据源内，如果在，用户可能正在拉取历史消息，或者查看历史消息，暂不清理，判断大于300，预留100个数据缓冲，避免用户感觉突兀
            if (indexPath.row > 300) {
                NSRange range = NSMakeRange(0, COLLECTION_VIEW_CELL_REMOVE_COUNT);
                [self.chatVC.conversationDataRepository removeObjectsInRange:range];
                [self.chatVC.conversationMessageCollectionView reloadData];
            }
        } else {
            //聊天页面生命周期未结束但是又不在当前展示页面，直接清理
            NSRange range = NSMakeRange(0, COLLECTION_VIEW_CELL_REMOVE_COUNT);
            [self.chatVC.conversationDataRepository removeObjectsInRange:range];
            [self.chatVC.conversationMessageCollectionView reloadData];
        }
    }
}


- (void)appendAndDisplayMessage:(RZMessage *)rzMessage {
    if (!rzMessage) {
        return;
    }
    __weak typeof(self) ws = self;
    RZConversationViewController *chatVC = self.chatVC;
    
    //在队列中进行消息的添加
    [self.appendMessageQueue addOperationWithBlock:^{
        
        //主队列处理
        dispatch_async(dispatch_get_main_queue(), ^{
            @autoreleasepool {
                if (!chatVC.needAutoScrollToBottom && chatVC.conversationDataRepository.count > 0) {
                    chatVC.needAutoScrollToBottom =
                        [chatVC.conversationMessageCollectionView
                            cellForItemAtIndexPath:[NSIndexPath indexPathForItem:chatVC.conversationDataRepository.count - 1
                                                                       inSection:0]] != nil;
                }

                RZMessageInfo *model = [RZMessageInfo createWithSocketMessage:rzMessage];
                
                if ([ws appendMessageModel:model]) {
                    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:chatVC.conversationDataRepository.count - 1 inSection:0];
                    if ([chatVC.conversationMessageCollectionView numberOfItemsInSection:0] !=
                        chatVC.conversationDataRepository.count - 1) {
                        NSLog(@"Error, datasource and collectionview are inconsistent!!");
                        [chatVC.conversationMessageCollectionView reloadData];
                        return;
                    }
                    [chatVC.conversationMessageCollectionView insertItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
                    [chatVC scrollToBottomAnimated:YES]; //滚动到底部
                    
//                    if (chatVC.needAutoScrollToBottom) {
//                        [chatVC scrollToBottomAnimated:YES];
//                        chatVC.needAutoScrollToBottom = NO;
//                    } else {
//                        if (chatVC.conversationType == ConversationType_CHATROOM) {
//                            [chatVC scrollToBottomAnimated:NO];
//                        }
//                    }
                }
            }
        });
        [NSThread sleepForTimeInterval:0.01];
    }];
}



/**
 真正的 - 往数据源中添加消息数据
 */
- (BOOL)appendMessageModel:(RZMessageInfo *)model {
    if (!model || ![model isKindOfClass:[RZMessageInfo class]]) {
        return NO;
    }
    
    long newId = model.mid;
    for (RZMessageInfo *__item in self.chatVC.conversationDataRepository) {

        /*
         * 当id为－1时，不检查是否重复，直接插入
         * 该场景用于插入临时提示。
         */
        if (newId == -1) {
            break;
        }
        if (newId == __item.mid) {
            return NO;
        }
    }


    model = [self setModelIsDisplayNickName:model];
    if (model) {
        [self.chatVC.conversationDataRepository addObject:model];
    }
    return YES;
}


/**
 根据控制器的设置 ，来改变模型对于是否显示昵称的控制
 */
- (RZMessageInfo *)setModelIsDisplayNickName:(RZMessageInfo *)model {
    if (!model) {
        return nil;
    }
    if (model.messageDirection == MessageDirection_RECEIVE) {
        model.isDisplayNickname = self.chatVC.displayUserNameInCell;
    } else {
        model.isDisplayNickname = NO;
    }
    return model;
}

@end
